Add examples/worker-javascript - #36
Merged
aron-cf merged 4 commits intoAug 3, 2026
Merged
Conversation
commit: |
| function errorJSON(error: unknown, status: number): Response { | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| const code = (error as { code?: string }).code; | ||
| return new Response(JSON.stringify({ error: message, code }), { |
aron-cf
force-pushed
the
stack/2-worker-javascript-example
branch
from
August 3, 2026 10:17
042ad76 to
619dff2
Compare
Mirror the worker-shell example with a Durable Object whose Workspace runs an ECMAScript module in a Dynamic Worker through the WorkerJavaScriptBackend. The DO class, HTTP routes, and R2 mount match worker-shell; the difference is the backend and what exec runs. The backend takes only the Loader binding, needs no WorkspaceServiceProxy loopback, and requires waitUntil, so the DO passes ctx.waitUntil.bind(ctx) into the Workspace options. The exec route accepts a module source plus an optional structured input and returns the run's status, streams, and the module's structured value. List the new example in the project layout doc.
The runtime rejected structured input for any command-routed backend, conflating two independent questions: which downstream surface a backend speaks, and whether it accepts a structured input value and returns a structured result. A shell backend that coerced JSON to argv and parsed stdout back to a value could not opt in. Add an optional callable capability to the backend interfaces, default false. The WorkerJavaScriptBackend declares it true. The runtime router now gates input on a callableBackendIds set built from that capability, independent of command-versus-module routing, and reports a clearer "not callable" error.
Explain callable next to the id and type discussion in the package README: a callable backend accepts a structured input value and returns a structured value, the runtime rejects input for a non-callable backend, and the capability is independent of the backend kind.
The callable gate rejects input for backends that are not in the callable set, but a command backend that declared itself callable would pass the gate and then have its input silently dropped, because the command branch never forwards input to the shell. Reject input on the command path directly so the drop can never happen, and cover it with a test.
aron-cf
force-pushed
the
stack/2-worker-javascript-example
branch
from
August 3, 2026 10:39
619dff2 to
a23e3e1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
worker-shellbackend has an example that shows how to drive it from a Durable Object, but theworker-javascriptbackend had none, so there was no worked reference for running a JavaScript module in a Worker isolate. This change adds anexamples/worker-javascriptthat mirrors the shell example beat for beat: the same Durable Object class, the same HTTP routes for writing files, reading them back, and running code, and the same R2 mount. Where the shell example runs a command, this one runs a JavaScript module and returns the value the module produces.Running a module with a structured input value and getting a structured value back is a different contract from a shell, which takes argv and stdin and returns a stream of bytes. To model that difference honestly, this change adds a
callablecapability to the backend interface. A callable backend is one you can hand a structured argument and that returns a structured value. The runtime router gates theinputoption on this declared capability rather than on the kind of backend, so the two axes stay independent: a shell backend that chose to accept structured input could also be callable. A call that passesinputto a backend that is not callable now fails with a clear message.Verify by running the example under
wrangler devand posting a module to its exec route, or run the router unit tests withnpm test --workspace @cloudflare/computer. The example is listed in the project layout documentation.